import { PrismaClient } from '@prisma/client'
import { getPrismaClient } from '../database/connection'
import { DatabaseRetryWrapper, CircuitBreaker } from '../database/retry'

// 基础服务类
export abstract class BaseService {
  protected prisma: PrismaClient
  protected retryWrapper: DatabaseRetryWrapper
  protected circuitBreaker: CircuitBreaker
  
  constructor() {
    this.prisma = getPrismaClient()
    this.retryWrapper = new DatabaseRetryWrapper()
    this.circuitBreaker = new CircuitBreaker()
  }
  
  // 执行数据库操作（带重试和熔断器）
  protected async executeWithResilience<T>(
    operation: () => Promise<T>,
    options: { useCircuitBreaker?: boolean; useRetry?: boolean } = {}
  ): Promise<T> {
    const { useCircuitBreaker = true, useRetry = true } = options
    
    let wrappedOperation = operation
    
    if (useRetry) {
      wrappedOperation = () => this.retryWrapper.execute(operation)
    }
    
    if (useCircuitBreaker) {
      return await this.circuitBreaker.execute(wrappedOperation)
    }
    
    return await wrappedOperation()
  }
  
  // 执行事务操作
  protected async executeTransaction<T>(
    operation: (tx: any) => Promise<T>
  ): Promise<T> {
    return await this.executeWithResilience(
      () => this.retryWrapper.executeTransaction(operation)
    )
  }
  
  // 健康检查
  async healthCheck(): Promise<boolean> {
    try {
      await this.executeWithResilience(
        () => this.prisma.$queryRaw`SELECT 1`,
        { useCircuitBreaker: false, useRetry: false }
      )
      return true
    } catch (error) {
      console.error('Service health check failed:', error)
      return false
    }
  }
  
  // 获取服务指标
  getMetrics() {
    return {
      circuitBreaker: this.circuitBreaker.getMetrics(),
      prisma: {} // Prisma metrics access removed due to type issues
    }
  }
}

// 服务接口
export interface IService {
  healthCheck(): Promise<boolean>
  getMetrics(): any
}

// 服务注册表
export class ServiceRegistry {
  private static instance: ServiceRegistry
  private services: Map<string, IService> = new Map()
  
  static getInstance(): ServiceRegistry {
    if (!ServiceRegistry.instance) {
      ServiceRegistry.instance = new ServiceRegistry()
    }
    return ServiceRegistry.instance
  }
  
  register(name: string, service: IService): void {
    this.services.set(name, service)
  }
  
  get<T extends IService>(name: string): T | undefined {
    return this.services.get(name) as T
  }
  
  async healthCheckAll(): Promise<Record<string, boolean>> {
    const results: Record<string, boolean> = {}
    
    // 使用 Array.from 来避免迭代器问题
    for (const [name, service] of Array.from(this.services.entries())) {
      try {
        results[name] = await service.healthCheck()
      } catch (error) {
        console.error(`Health check failed for service ${name}:`, error)
        results[name] = false
      }
    }
    
    return results
  }
  
  getAllMetrics(): Record<string, any> {
    const metrics: Record<string, any> = {}
    
    // 使用 Array.from 来避免迭代器问题
    for (const [name, service] of Array.from(this.services.entries())) {
      try {
        metrics[name] = service.getMetrics()
      } catch (error) {
        console.error(`Failed to get metrics for service ${name}:`, error)
        const errorMessage = error instanceof Error ? error.message : String(error)
        metrics[name] = { error: errorMessage }
      }
    }
    
    return metrics
  }
}
